package com.zero.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import com.zero.user.User;
import com.zero.util.Codec;

/**
 * 服务器端读写类线程 用于服务器端读取客户端的信息，并把信息发送给所有客户端
 * 
 * @author Zero
 */
class ServerIOThread extends Thread {
	private Socket socket;
	private User me;
	private static ServerView serverView;
	private static List<User> users = new ArrayList<User>();// user列表
	private BufferedReader bufferedReader;
	private PrintWriter printWriter;

	public ServerIOThread(Socket socket, ServerView serverView) throws IOException {
		this.socket = socket;
		ServerIOThread.serverView = serverView;
		bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		printWriter = new PrintWriter(socket.getOutputStream());
	}

	@Override
	public void run() {
		try {
			String instruction = null;
			while ((instruction = bufferedReader.readLine()) != null) {
				if ("connect".equals(instruction)) {
					String name = Codec.decode(bufferedReader.readLine());
					String nickname = Codec.decode(bufferedReader.readLine());
					String password = Codec.decode(bufferedReader.readLine());

					me = new User(name, nickname, password, socket);

					if (users.stream().anyMatch(u -> u.getName().equals(name))) {
						printWriter.write(Codec.encode("repeat login") + "\n");
						printWriter.flush();

						User user = users.parallelStream().filter(u -> u.getName().equals(name)).findAny().orElse(null);
						PrintWriter pw = new PrintWriter(user.getSocket().getOutputStream());
						pw.write(Codec.encode("系统提示：有人登录了您的账号，已帮您强制下线，为了您的安全，请修改密码！！！（当然，我们还没有此功能）") + "\n");
						pw.flush();

						serverView.setTextArea("客户端" + name + "（" + nickname + "）" + "重复登录\n");

						socket.shutdownInput();
						return;
					} else {
						users.add(me);// 添加到列表

						PrintWriter pw = null;// 当前遍历用户的Socket的PrintWriter
						for (User user : users) {
							// 如果是不是自己
							if (!user.equals(me)) {
								pw = new PrintWriter(user.getSocket().getOutputStream());
								pw.write(Codec.encode("欢迎" + name + "（" + nickname + "）" + "进入聊天室") + "\n");
								pw.flush();
							} else {
								printWriter.write(Codec.encode("您已进入聊天室") + "\n");
								printWriter.flush();
							}
						}

						serverView.setTextArea("客户端" + name + "（" + nickname + "）" + "连接服务器成功\n");
					}

				} else if ("HeartBeat".equals(instruction)) {
					String heartBeat = bufferedReader.readLine();
					serverView.setTextArea(
							"收到客户端" + me.getName() + "（" + me.getNickname() + "）" + "的心跳包：" + heartBeat + "\n");
				} else if ("send".equals(instruction)) {
					String to = Codec.decode(bufferedReader.readLine());
					String message = Codec.decode(bufferedReader.readLine());

					User userTo = users.parallelStream().filter(u -> u.getName().equals(to)).findAny().orElse(null);
					if (userTo == null) {
						printWriter.write(Codec.encode("系统提示：没有该用户（" + to + "）在线") + "\n");
						printWriter.flush();
						continue;
					}
					if (userTo.equals(me)) {
						printWriter.write(Codec.encode("系统提示：请不要给自己发消息哦") + "\n");
						printWriter.flush();
						continue;
					}

					PrintWriter pw = new PrintWriter(userTo.getSocket().getOutputStream());
					pw.write(Codec.encode(me.getName() + "（" + me.getNickname() + "）发给您：" + message) + "\n");
					pw.flush();

					printWriter.write(Codec.encode("您发给" + to + "（" + userTo.getNickname() + "）：" + message) + "\n");
					printWriter.flush();

					serverView.setTextArea("客户端" + me.getName() + "（" + me.getNickname() + "）" + "给客服端" + to + "（"
							+ userTo.getNickname() + "）私发了信息\n");
				} else if ("sendAll".equals(instruction)) {
					String message = Codec.decode(bufferedReader.readLine());

					PrintWriter pw = null;// 当前遍历用户的Socket的PrintWriter
					for (User user : users) {
						// 如果是不是自己
						if (!user.equals(me)) {
							pw = new PrintWriter(user.getSocket().getOutputStream());
							pw.write(Codec
									.encode("来自<-" + me.getName() + "（" + me.getNickname() + "）->" + "的群发消息：" + message)
									+ "\n");
							pw.flush();
						} else {
							printWriter.write(Codec.encode("您的群发消息：" + message) + "\n");
							printWriter.flush();
						}
					}
					serverView.setTextArea("客户端" + me.getName() + "（" + me.getNickname() + "）" + "群发了信息\n");
				} else if ("disconnect".equals(instruction)) {
					serverView.setTextArea(me.getName() + "（" + me.getNickname() + "）" + "已断开\n");
					PrintWriter pw = null;// 当前遍历用户的Socket的PrintWriter
					for (User user : users) {
						// 如果是不是自己
						if (!user.equals(me)) {
							pw = new PrintWriter(user.getSocket().getOutputStream());
							pw.write(Codec.encode(me.getName() + "（" + me.getNickname() + "）" + "已下线") + "\n");
							pw.flush();
						}
					}
					users.remove(me);
					socket.shutdownInput();
				} else {
					throw new IllegalArgumentException("错误指令：" + instruction);
				}
			}
		} catch (IllegalArgumentException e) {
			printWriter.write(e.getMessage() + "！！！\n");
			printWriter.flush();
		} catch (SocketException e) {
			SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(serverView,
					"客服端" + me.getName() + "（" + me.getNickname() + "）" + "已断开" + "\n" + e.getMessage(), "提示",
					JOptionPane.WARNING_MESSAGE));
		} catch (IOException e) {
			SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(serverView,
					"读取socket输入输出流错误\n" + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE));
		}
	}
}
